﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sealight.Core.Domain;
using Sealight.API.Framework;
using NHibernate;
using NHibernate.Linq;

namespace Sealight.Data
{
    public class ProductDataRepository : NHibernateRepository<ProductEntity>, IProductDataRepository
    {

        public ProductVariantEntity SaveOrUpdateProductVariant(ProductVariantEntity entity)
        {
            try
            {
                UnitOfWork.CurrentSession.SaveOrUpdate(entity);
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
            return entity;
        }

        public ProductVariantEntity GetProductVariantByID(Guid id)
        {
            ProductVariantEntity result = null;
            try
            {
                result = UnitOfWork.CurrentSession.Get<ProductVariantEntity>(id);
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }

            return result;
        }

        public PictureEntity AddPicture(PictureEntity entity)
        {
            try
            {
                UnitOfWork.CurrentSession.SaveOrUpdate(entity);
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }

            return entity;
        }

        public PictureEntity GetPictureByID(Guid id)
        {
            PictureEntity result = null;
            try
            {
                result = UnitOfWork.CurrentSession.Get<PictureEntity>(id);
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }

            return result;
        }

        public void DeletePicture(PictureEntity pic)
        {
            try
            {
                UnitOfWork.CurrentSession.Delete(pic);
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
        }

        public void MapCategoryToProduct(ProductCategoryEntity categoryMap)
        {
            try
            {
                UnitOfWork.CurrentSession.SaveOrUpdate(categoryMap);
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
        }

        public CategoryEntity GetProductCategoryByID(Guid id)
        {
            CategoryEntity result = null;
            try
            {
                result = UnitOfWork.CurrentSession.Get<CategoryEntity>(id);
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }

            return result;
        }
        public IList<CategoryEntity> GetCategoryByParentID(Guid id)
        {
            IList<CategoryEntity> result = null;
            try
            {
                IQueryable<CategoryEntity> data = UnitOfWork.CurrentSession.Query<CategoryEntity>();
                if (id == Guid.Empty)
                {
                    result = data.Where(c => c.ParentID == null || c.ParentID == Guid.Empty).ToList();
                }
                else
                {
                    result = data.Where(c => c.ParentID == id).ToList();
                }
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
            return result;
        }
        public IList<SpecificationAttributeOptionEntity> GetAllOptionBySpecificationId(Guid id)
        {
            IList<SpecificationAttributeOptionEntity> result = null;
            try
            {
                IQueryable<SpecificationAttributeOptionEntity> data = UnitOfWork.CurrentSession.Query<SpecificationAttributeOptionEntity>();
                result = data.Where(c => c.SpecificationAttribute.SpecificationAttributeID == id).ToList();
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
            return result;
        }
        public IList<RelatedProductEntity> GetRelatedProducts(Guid productId)
        {
            IList<RelatedProductEntity> result = null;
            try
            {
                IQueryable<RelatedProductEntity> data = UnitOfWork.CurrentSession.Query<RelatedProductEntity>();
                result = data.Where(c => c.Product1.ProductID == productId).ToList();
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
            return result;
        }
        public IList<ProductEntity> SearchProduct(string keyword, Guid categoryId)
        {
            IList<ProductEntity> result = null;
            try
            {
                IQueryable<ProductEntity> data = UnitOfWork.CurrentSession.Query<ProductEntity>();

                if (categoryId != Guid.Empty)
                {
                    if (!string.IsNullOrEmpty(keyword))
                    {
                        result = data.Where(c => c.Name.Contains(keyword) &&
                            (c.CategoryMaps.Where(g => g.Category.CategoryID == categoryId).Count() > 0)).ToList();
                    }
                    else
                    {
                        result = data.Where(c =>(c.CategoryMaps.Where(g => g.Category.CategoryID == categoryId).Count() > 0)).ToList();
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(keyword))
                    {
                        result = data.Where(c => c.Name.Contains(keyword)).ToList();
                    }
                    else
                    {
                        result = data.ToList();
                    }
                }
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
            return result;

        }

        public IList<ProductVariantAttributeEntity> GetProductVariantAttribute(Guid productVariantId)
        {
            IList<ProductVariantAttributeEntity> result = null;
            try
            {
                IQueryable<ProductVariantAttributeEntity> data = UnitOfWork.CurrentSession.Query<ProductVariantAttributeEntity>();
                result = data.Where(c=>c.ProductVariant.ProductVariantID == productVariantId).ToList();
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
            return result;
        }
        public IList<ProductVariantAttributeValueEntity> GetProductVariantAttributeValue(Guid productVariantAttributeId)
        {
            IList<ProductVariantAttributeValueEntity> result = null;
            try
            {
                IQueryable<ProductVariantAttributeValueEntity> data = UnitOfWork.CurrentSession.Query<ProductVariantAttributeValueEntity>();
                result = data.Where(c => c.ProductVariantAttribute.ProductVariantAttributeID == productVariantAttributeId).ToList();
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
            return result;
        }
        public IList<ProductSpecificationAttributeEntity> GetSpecificationOptionAttributeForProduct(Guid id)
        {
            IList<ProductSpecificationAttributeEntity> result = null;
            try
            {
                IQueryable<ProductSpecificationAttributeEntity> data = UnitOfWork.CurrentSession.Query<ProductSpecificationAttributeEntity>();
                result = data.Where(c => c.Product.ProductID == id).ToList();
            }
            catch (ADOException ex)
            {
                //rethrow the exception
                throw;
            }
            return result;

        }
    }
}
